package model;

public class Road {
	public String name = "Unnamed";
	private Junction sideA;
	private Junction sideB;
	
	private double length;
	private double speed;
	private static double DEF_DENSITY = 10;
	private double maxdensity = DEF_DENSITY;
	private double nrOfVehicles = 0;
	
	public Road(Junction j, Junction j2, String name, double length, double speed){
		this(j, j2, name, length , speed, DEF_DENSITY);
	}
	
	public Road(Junction j, Junction j2, String name, double length, double speed, double maxDensity){
		this.name = name;
		this.length = length;
		this.speed = speed;
		this.maxdensity = maxDensity;
		
		j.add(this);
		j2.add(this);
	}
	
	public Road(){
		
	}
	
	public double getLength(){
		return length;
	}
	
	public void addVehicles(double amount){
		this.nrOfVehicles += amount;
		
		assert ((double)nrOfVehicles) / length < maxdensity : "To many vehicles on road:" + this;
	}
	
	public void reset(double amount){
		this.nrOfVehicles = amount;
	}
	
	private double density(){
		return nrOfVehicles / length;
	}
	
	public double getTravelTime(){
		
		return density();//length / (speed * ( 1 - density()/maxdensity));
	}
	
	public void connect(Junction j) throws IllegalStateException{
		if(sideA == null)
			sideA = j;
		else if(sideB == null)
			sideB = j;
		else
			throw new IllegalStateException("Cannot connect to more than two junctions");
	}
	
	public boolean isValid(){
		return (sideA != null) && (sideB != null);
	}
	
	public String toString(){
		return name;
	}

	public boolean isConnectedTo(Junction j) {
		return (sideA == j) || (sideB == j);
	}

	public Junction getSideA() {
		return sideA;
	}
	
	public Junction getSideB(){
		return sideB;
	}

	public Junction otherSide(Junction j) {
		assert isConnectedTo(j) : "There is no such junction connected to this road";
		
		if(sideA == j)
			return sideB;
		else
			return sideA;
	}

	public boolean isConnectedTo(Road j) {
		return j.isConnectedTo(sideA) || j.isConnectedTo(sideB);
	}
}
